import { _decorator, Animation, AudioClip, Collider, Collider2D, Component, Contact2DType, EventTouch, Input, input, instantiate, IPhysics2DContact, Node, Prefab, Sprite, Vec3 } from 'cc';
import { Reward, RewardType } from './Reward';
import { GameManager } from './GameManager';
import { LifeCountUI } from './UI/LifeCountUI';
import { AudioMgr } from './AudioMgr';
const { ccclass, property } = _decorator;

enum ShootType {
    None,
    OneShoot,
    TwoShoot
}

@ccclass('Player')
export class Player extends Component {

    @property
    shootRate: number = 0.5;
    @property(Prefab)
    bullet1Prefab: Prefab = null;
    @property(Node)
    bulletParent: Node = null;
    @property(Node)
    position1: Node = null;

    @property(Prefab)
    bullet2Prefab: Prefab = null;
    @property(Node)
    position2: Node = null;
    @property(Node)
    position3: Node = null;

    @property
    shootType: ShootType = ShootType.OneShoot;

    @property
    liftCount: number = 3;
    @property(Animation)
    anim: Animation = null;
    @property
    animHit: string = "";
    @property
    animDown: string = "";
    shootTimer: number = 0;

    @property
    twoShootTime: number = 10;
    @property
    twoShootTimer: number = 0;

    @property(LifeCountUI)
    lifeCountUI:LifeCountUI=null;
    @property(AudioClip)
    bulletAudio:AudioClip=null;


    @property
    invincibleTime: number = 1;
    invincibleTimer: number = 0;

    isInvincible: boolean = false;

    collider: Collider2D = null;
    private canControl:boolean=true;


    protected onLoad(): void {
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);

        // 注册单个碰撞体的回调函数
        this.collider = this.getComponent(Collider2D);
        if (this.collider) {
            this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        }
    }
    protected start():void{
        this.lifeCountUI.updateUI(this.liftCount);
    }
    //销毁事件
    protected onDestroy(): void {
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        if (this.collider) {
            this.collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        }
    }

    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {

        const reward = otherCollider.getComponent(Reward);
        if (reward) {
            this.onContactToReward(reward);
        } else {
            this.onContactToEnemy();
        }
    }

    transitionToTwoShoot() {
        this.shootType = ShootType.TwoShoot;
        this.twoShootTimer = 0;
    }
    transitionToOneShoot() {
        this.shootType = ShootType.OneShoot;
    }
    lastReward:Reward=null;

    onContactToReward(reward:Reward) {
        if(reward==this.lastReward){
            return;
        }
        this.lastReward=reward;
        if (reward.rewardType == RewardType.TwoShoot) {
            this.transitionToTwoShoot();
        } else {
            GameManager.getInstance().AddBomb();
        }
        reward.getComponent(Collider2D).enabled=false;
        reward.getComponent(Sprite).enabled=false;
    }
    onContactToEnemy() {
        if (this.isInvincible) {
            return;
        }
        this.isInvincible = true;
        this.invincibleTimer = 0;

        // this.liftCount -= 1;
        this.changeLifeCount(-1);
        if (this.liftCount > 0) {
            this.anim.play(this.animHit);
        } else {
            this.anim.play(this.animDown);
        }

        if (this.liftCount <= 0) {
            if (this.collider) {
                this.shootType = ShootType.None;
                this.collider.enabled = false;
            }
            this.scheduleOnce(()=>{
                GameManager.getInstance().gameOver();
            },0.4);
        }
    }
    changeLifeCount(count:number){
        this.liftCount+=count;
        this.lifeCountUI.updateUI(this.liftCount);
    }

    onTouchMove(event: EventTouch) {
        if(this.canControl==false){
            return;
        }
        if (this.liftCount <= 0) {
            return;
        }
        const p = this.node.position;
        let targetPosition = new Vec3(p.x + event.getDeltaX(), p.y + event.getDeltaY(), p.z);

        //判断是否超出屏幕
        if (targetPosition.x < -230) {
            targetPosition.x = -230
        }
        if (targetPosition.x > 230) {
            targetPosition.x = 230
        }
        if (targetPosition.y < -380) {
            targetPosition.y = -380
        }
        if (targetPosition.y > 380) {
            targetPosition.y = 380
        }

        this.node.setPosition(targetPosition);
    }

    protected update(dt: number): void {
        switch (this.shootType) {
            case ShootType.OneShoot:
                this.oneShoot(dt);
                break;
            case ShootType.TwoShoot:
                this.twoShoot(dt);
                break;

        }
        //无敌时间
        if (this.isInvincible) {
            this.invincibleTimer += dt;
            if (this.invincibleTimer > this.invincibleTime) {
                this.isInvincible = false;
            }
        }

    }

    oneShoot(dt: number) {
        this.shootTimer += dt;
        if (this.shootTimer > this.shootRate) {
            AudioMgr.inst.playOneShot(this.bulletAudio,0.2);
            this.shootTimer = 0;
            const bullet1 = instantiate(this.bullet1Prefab);
            this.bulletParent.addChild(bullet1)
            bullet1.setWorldPosition(this.position1.worldPosition)
        }
    }
    twoShoot(dt: number) {
        //双发时间
        this.twoShootTimer += dt;
        if (this.twoShootTimer > this.twoShootTime) {
            this.transitionToOneShoot();
        }

        this.shootTimer += dt;
        if (this.shootTimer > this.shootRate) {
            AudioMgr.inst.playOneShot(this.bulletAudio,0.2);
            this.shootTimer = 0;
            const bullet1 = instantiate(this.bullet2Prefab);
            const bullet2 = instantiate(this.bullet2Prefab);

            this.bulletParent.addChild(bullet1)
            this.bulletParent.addChild(bullet2)

            bullet1.setWorldPosition(this.position2.worldPosition)
            bullet2.setWorldPosition(this.position3.worldPosition)
        }
    }

    disableControl(){
        this.canControl=false;
    }
    enableControl(){
        this.canControl=true;
    }

}


